package com.weixu.fileconver.util;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.RuntimeUtil;
import cn.hutool.core.util.StrUtil;
import com.weixu.fileconver.config.LibreOfficeConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;

/**
 * LibreOffice转换工具类
 *
 * @Author weixu
 * @Date 2025/8/29
 */
@Component
public class LibreOfficeUtil {

    private static final Logger logger = LoggerFactory.getLogger(LibreOfficeUtil.class);

    @Autowired
    private LibreOfficeConfig libreOfficeConfig;

    /**
     * 将Office文件转换为指定格式
     *
     * @param inputFile  输入文件
     * @param outputDir  输出目录
     * @param targetType 目标格式（如：pdf, doc, docx, xls, xlsx, ppt, pptx, odt, ods, odp等）
     * @return 转换后的文件
     * @throws Exception 转换异常
     */
    public File convertToFormat(File inputFile, String outputDir, String targetType) throws Exception {
        if (!inputFile.exists()) {
            throw new FileNotFoundException("输入文件不存在: " + inputFile.getAbsolutePath());
        }

        // 确保输出目录存在
        FileUtil.mkdir(outputDir);

        // 获取文件名（不含扩展名） 
        String fileName = FileUtil.getPrefix(inputFile);
        File outputFile = new File(outputDir, fileName + "." + targetType);

        logger.info("开始转换文件: {} -> {} (格式: {})", inputFile.getAbsolutePath(),
                outputFile.getAbsolutePath(), targetType);

        // 获取LibreOffice可执行文件路径
        String executablePath = libreOfficeConfig.getExecutablePath();
        logger.info("使用LibreOffice路径: {}", executablePath);

        try {
            // 构建命令参数列表
            List<String> commandList = new ArrayList<>();
            commandList.add(executablePath);
            commandList.add("--headless");
            commandList.add("--convert-to");
            commandList.add(targetType);

            // 检查是否需要添加特殊的输入过滤器参数
            String inputExtension = FileUtil.getSuffix(inputFile).toLowerCase();
            if ("pdf".equals(inputExtension) && ("docx".equals(targetType.toLowerCase()) ||
                    "doc".equals(targetType.toLowerCase()))) {
                commandList.add("--infilter=writer_pdf_import");
                logger.info("检测到PDF转DOCX，添加writer_pdf_import过滤器");
            }

            commandList.add("--outdir");
            commandList.add(outputDir);
            commandList.add(inputFile.getAbsolutePath());

            logger.info("执行命令: {}", String.join(" ", commandList));

            // 使用RuntimeUtil执行命令，设置超时时间
            String result = RuntimeUtil.execForStr(commandList.toArray(new String[0]));

            logger.info("LibreOffice执行结果: {}", result);

            // 检查输出文件是否生成 
            if (!outputFile.exists()) {
                throw new RuntimeException("转换完成但未找到输出文件: " + outputFile.getAbsolutePath());
            }

            logger.info("文件转换成功: {}", outputFile.getAbsolutePath());
            return outputFile;

        } catch (Exception e) {
            logger.error("LibreOffice转换失败: {}", e.getMessage(), e);
            throw new Exception("LibreOffice转换失败: " + e.getMessage(), e);
        }
    }

    /**
     * 检查文件是否支持转换
     *
     * @param fileName 文件名
     * @return 是否支持
     */
    public boolean isSupportedFormat(String fileName) {
        if (StrUtil.isBlank(fileName)) {
            return false;
        }

        String extension = FileUtil.getSuffix(fileName).toLowerCase();

        // 支持的文件格式（包括PDF）
        String[] supportedFormats = {
                "doc", "docx", "xls", "xlsx", "ppt", "pptx",
                "odt", "ods", "odp", "rtf", "txt", "pdf"
        };

        for (String format : supportedFormats) {
            if (format.equals(extension)) {
                return true;
            }
        }

        return false;
    }

    /**
     * 检查LibreOffice是否可用
     *
     * @return 是否可用
     */
    public boolean isLibreOfficeAvailable() {
        try {
            String executablePath = libreOfficeConfig.getExecutablePath();
            File executable = new File(executablePath);
            return executable.exists() && executable.canExecute();
        } catch (Exception e) {
            logger.error("检查LibreOffice可用性失败", e);
            return false;
        }
    }
}